package com.black.knight.chess;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.Signature;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.Base64;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.Surface;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup.LayoutParams;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.AccelerateDecelerateInterpolator;
import android.view.animation.RotateAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.GridView;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.black.knight.chess.adapters.DestroyedFiguresAdapter;
import com.black.knight.chess.adapters.TableAdapter;
import com.black.knight.chess.domain.ChessCommand;
import com.black.knight.chess.domain.Game;
import com.black.knight.chess.domain.Move;
import com.black.knight.chess.domain.Player;
import com.black.knight.chess.enums.ChessAction;
import com.black.knight.chess.enums.CommandType;
import com.black.knight.chess.enums.NewGame;
import com.black.knight.chess.model.PNGGamesModel;
import com.black.knight.chess.model.SahModel;
import com.black.knight.chess.model.SettingsModel;
import com.black.knight.chess.plugins.BluetoothPlugin;
import com.black.knight.chess.utils.ChessUtil;
import com.black.knight.chess.utils.Utils;
import com.facebook.android.Facebook;
import com.google.ads.AdRequest;
import com.google.ads.AdSize;
import com.google.ads.AdView;

public class SahMatActivity extends Activity {
    	
	private Move move;   
    
    private static boolean firstCall = true;
    
    private TextView evalTextView;

	private ImageView imageViewKnight;
    private ImageView emptyViewKnight;
    
    private static Long lastBackPressed;
    
    public Menu menu;
    
    private AdView adView;
    
    //private Timer timer;

	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);

    	requestWindowFeature(Window.FEATURE_NO_TITLE);
        
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 
                                WindowManager.LayoutParams.FLAG_FULLSCREEN);

    	
    	SahModel.context = this;
    	
    	Utils.setLanguage(SettingsModel.getInstance().getLanguage(), SahModel.context);
    	
    	/*if(firstCall && SettingsModel.getInstance().isAutoLogIn()) {
    		User user = new User();
    		user.setUsername(SettingsModel.getInstance().getUsername());
    		user.setPassword(SettingsModel.getInstance().getPassword());
    		
    		AutoLoginUserCall call = new AutoLoginUserCall(user, this);
    		
    		SettingsModel.EXECUTOR_SERVICE.execute(call);
    	} else if(firstCall && SettingsModel.getInstance().isAutoLogInWithFacebook()) { 
    		User user = new User();
    		user.setUsername(SettingsModel.getInstance().getUsername());
    		
    		AutoLoginFacebookUserCall call = new AutoLoginFacebookUserCall(user, this);
    		
    		SettingsModel.EXECUTOR_SERVICE.execute(call);
    	}*/
    	refresh(getResources().getConfiguration());
    	
    	PNGGamesModel.getInstance();
    	
    	/*timer = new Timer();
    	timer.schedule(new TimerTask() {
			@Override
			public void run() {
	    		if(SettingsModel.getInstance().getLoggedUser() != null) {
	        		PublishActivityCall call = new PublishActivityCall(SettingsModel.getInstance().getLastActivity(), SettingsModel.getInstance().getLoggedUser().getUsername(), SettingsModel.getInstance().getLoggedUser().getName(), "");			    		
	        		SettingsModel.EXECUTOR_SERVICE.execute(call);
	        	}
			}
		}, 300 * 1000, 300 * 1000);*/
    }
    
    @Override
    public void onPause() {
    	super.onPause();
    	
    	if(!NewGame.BLUETOOTH.equals(SahModel.getInstance().getGame().getGameType())) {
	    	SahModel.getInstance().getBlackClock().stop();
	    	SahModel.getInstance().getWhiteClock().stop();
    	}
    }
    
    @Override
    public void onBackPressed() {
    	if(lastBackPressed != null && lastBackPressed + 2500 > System.currentTimeMillis()) {
			if(NewGame.BLUETOOTH == SahModel.getInstance().getGame().getGameType()) {
				ChessCommand cmd = new ChessCommand();
	    		cmd.setType(CommandType.STOP);
				
	    		BluetoothPlugin.getInstance().sendCommand(cmd);
			}
			
			/*if(SettingsModel.getInstance().getLoggedUser() != null) {
				PublishActivityCall call = new PublishActivityCall(ActivityEnum.SIGN_OUT, SettingsModel.getInstance().getLoggedUser().getUsername(), SettingsModel.getInstance().getLoggedUser().getName(), "");			    		
				SettingsModel.EXECUTOR_SERVICE.execute(call);
				try { Thread.sleep(500); } catch (Exception e) { }
			}*/
			
        	BluetoothPlugin.getInstance().stop();
        	finish();
        	System.exit(0);
    	} else {
    		lastBackPressed = System.currentTimeMillis();
    		Utils.displayToastMessage(this, getResources().getString(R.string.pres_back_again_to_exit));
    	}
    }
    
    @Override
    public void onResume() {
    	super.onResume();
        
    	final Facebook facebook = SahModel.getInstance().facebook;
        facebook.extendAccessTokenIfNeeded(this, null);
    	
    	if(SahModel.getInstance().getGame().getGameType() != null && SahModel.getInstance().getGame().isPlayOnClock() && !NewGame.BLUETOOTH.equals(SahModel.getInstance().getGame().getGameType())) {
			if(SahModel.getInstance().getGame().getPlayer1().isWhitePlayer()) {
				SahModel.getInstance().getWhiteClock().start();
			} else {
				SahModel.getInstance().getBlackClock().start();
			}
		}
    	
    	refresh(getResources().getConfiguration());
    }
    
    public void refresh(Configuration config) {             	
    	if(config.orientation == Configuration.ORIENTATION_LANDSCAPE) {
    		setContentView(R.layout.horizontalmain);
    	} else {
    		setContentView(R.layout.main);
    	}
    	
/*    	if(Utils.getOrientation() == Surface.ROTATION_0 || Utils.getOrientation() == Surface.ROTATION_180) {
    		setContentView(R.layout.main);
         } else {
        	setContentView(R.layout.horizontalmain);
         }*/
    	
    	 LinearLayout gridlayout = (LinearLayout) findViewById(R.id.gridlayout);
         
     	 // Initialize gridview
    	 GridView gridview = (GridView) findViewById(R.id.gridview);
         gridview.setSelector(R.drawable.empty);
         gridview.setAdapter(new TableAdapter(this));
         gridview.setAddStatesFromChildren(true);
         gridview.setOnItemClickListener(itemClickListener);
         gridview.setFastScrollEnabled(true);
         gridview.setClipChildren(true);
         
         if(SahModel.getInstance().getGame().getPlayer1().isWhitePlayer()) {
         	gridview.setBackgroundResource(R.drawable.background);
         } else {
         	gridview.setBackgroundResource(R.drawable.background1);
         }
         
         // Initialize buttons listeners
         ImageButton buttonPrevious = (ImageButton) findViewById(R.id.buttonPrevious);
         ImageButton buttonNext = (ImageButton) findViewById(R.id.buttonNext);
         
         buttonPrevious.setOnClickListener(previousClickListener);
         buttonNext.setOnClickListener(nextClickListener);
         
         buttonNext.setOnLongClickListener(new View.OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				goToEnd();
				
				return false;
			}
		});
         
         buttonPrevious.setOnLongClickListener(new View.OnLongClickListener() {
			@Override
			public boolean onLongClick(View v) {
				goToStart();
				
				return true;
			}
		});
         
         // Initialize destroyed layouts
         GridView destroyedWhiteFigures = (GridView) findViewById(R.id.destroyedWhiteFigures);
         destroyedWhiteFigures.setAdapter(new DestroyedFiguresAdapter(this, true));
         destroyedWhiteFigures.setVerticalScrollBarEnabled(false);
         destroyedWhiteFigures.setEnabled(false);
         destroyedWhiteFigures.setSelector(R.drawable.empty); 
         destroyedWhiteFigures.setClickable(false);
         destroyedWhiteFigures.setFastScrollEnabled(true);
         destroyedWhiteFigures.setClipChildren(true);
         destroyedWhiteFigures.setAddStatesFromChildren(true);
         
         GridView destroyedBlackFigures = (GridView) findViewById(R.id.destroyedBlackFigures);
         destroyedBlackFigures.setAdapter(new DestroyedFiguresAdapter(this, false));
         destroyedBlackFigures.setVerticalScrollBarEnabled(false);
         destroyedBlackFigures.setEnabled(false);
         destroyedBlackFigures.setSelector(R.drawable.empty);
         destroyedBlackFigures.setClickable(false);
         destroyedBlackFigures.setFastScrollEnabled(true);
         destroyedBlackFigures.setClipChildren(true);
         destroyedBlackFigures.setAddStatesFromChildren(true);
         
         refreshHeader();
         
         showArrows();
         
         if(firstCall) {
         	firstCall = !firstCall;
         	Utils.chooseNewGameType(this);
         }
         
         if(SahModel.getInstance().getGame() != null) {
        	 if(SahModel.getInstance().getGame().getSelectedIndex() == SahModel.getInstance().getGame().getMoves().size()) {
        		 refreshMovesManager(SahModel.getInstance().getGame().getSelectedIndex() - 1);
        	 } else {        		 refreshMovesManager(SahModel.getInstance().getGame().getSelectedIndex());
        	 }
         }         
         
         if(SahModel.screenHeight == 0) {
        	 SahModel.screenHeight = this.getWindow().getWindowManager().getDefaultDisplay().getHeight();
         }
         if(SahModel.screenWidth == 0) {
        	 SahModel.screenWidth = this.getWindow().getWindowManager().getDefaultDisplay().getWidth();
         }
         
         LayoutParams params = gridview.getLayoutParams();
         params.width = SahModel.getTableWidth();
         params.height = SahModel.getTableWidth();
         gridview.setLayoutParams(params);
         
         LayoutParams params1= gridlayout.getLayoutParams();
         gridlayout.measure(100, 100);
         gridview.measure(100, 100);
         if(Utils.getOrientation() == 1) {
        	 params1.width = LayoutParams.WRAP_CONTENT;
        	 params1.height = SahModel.getTableWidth();
         } else {
        	 params1.height = LayoutParams.WRAP_CONTENT;
        	 params1.width = SahModel.getTableWidth();
         }
                  
         gridlayout.setLayoutParams(params1);
         
         if(getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
        	 requestAd();
         }
    }
    
    public void requestAd() {
     	try {
     		LinearLayout adViewContainer = (LinearLayout) findViewById(R.id.adViewContainer);
	    	adViewContainer.setVisibility(AdView.VISIBLE);
	    	
	    	adView = new AdView(this, AdSize.SMART_BANNER, "7f7949a910044de0");
	    	
	    	adViewContainer.removeAllViews();
	    	adViewContainer.addView(adView);
	    	
	    	AdRequest req = new AdRequest();
	     	
	    	adView.loadAd(req);
     	} catch (Exception e) {
		}
    }
    
    public void hideAd() {
    	try {
    		if(getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
    			LinearLayout adViewContainer = (LinearLayout) findViewById(R.id.adViewContainer);
    			adViewContainer.setVisibility(AdView.INVISIBLE);
    		}
    	} catch (Exception e) { }
    }
    
    public void playNext() {
    	Game game = SahModel.getInstance().getGame();
		
		if(game.getSelectedIndex() < game.getMoves().size()) {
			if(NewGame.BLUETOOTH.equals(game.getGameType()) && game.getWinner() == null) return;
			
			//if(checkIfGameIsFinished(game.getMoves().get(game.getSelectedIndex()))) return;
			
			Move move = SahModel.getInstance().play(game.getSelectedIndex(), false);
			
			refreshMovesManager(game.getSelectedIndex());
			
			game.setSelectedIndex(game.getSelectedIndex() + 1);
			
			if((NewGame.COMPUTER.equals(game.getGameType()) || NewGame.SOLVE_PROBLEM.equals(game.getGameType())) && !move.isEndGame() && game.getSelectedIndex() < game.getMoves().size()) {
				move = SahModel.getInstance().play(game.getSelectedIndex(), false);
				
				refreshMovesManager(game.getSelectedIndex());
				
				game.setSelectedIndex(game.getSelectedIndex() + 1);
			}
			
			if(move.isCastle()) {
				Utils.playCastle();
			} else if(move.getDestroyedFigure() != R.drawable.selector && move.getDestroyedFigure() != R.drawable.empty) {
				Utils.playCapture();
			} else {
				Utils.playMove();
			}
			
			clearFilters();
			refreshDestroyedFigures();
			
			if(SettingsModel.getInstance().isRecognizeGame()) ChessUtil.displayCurrentOpening();
			
			if(!game.isFinished() && SahModel.getInstance().getGame().isPlayOnClock() && !NewGame.ANALIZE.equals(game.getGameType())) {
				SahModel.getInstance().toggleClocks();
			}
			
			if(SahModel.getInstance().isAutoRotate() && !game.isTimeout() && NewGame.HUMAN.equals(game.getGameType())) rotate();
			
			showArrows();
			filterLastMove(move);
			
			SahModel.lastAction = ChessAction.NEXT_MOVE;
			
			if(game.getSelectedIndex() < game.getMoves().size()) {
				checkIfGameIsFinished(game.getSelectedIndex());
			}
		}
    }
    
    public void playPrevious() {
    	Game game = SahModel.getInstance().getGame();
		
		if(game.getSelectedIndex() >= 1) {
			if(NewGame.BLUETOOTH.equals(game.getGameType()) && game.getWinner() == null) return;
			
			if(game.isSahMat() && !game.isTimeout() && !NewGame.BLUETOOTH.equals(game.getGameType())) {
				game.setWinner(null);
			}
			
			game.setSelectedIndex(game.getSelectedIndex() - 1);
			
			Move move = SahModel.getInstance().play(game.getSelectedIndex(), true);
			
			if((NewGame.COMPUTER.equals(game.getGameType()) || NewGame.SOLVE_PROBLEM.equals(game.getGameType())) && game.getSelectedIndex() > 0 && game.getSelectedIndex() % 2 == 1) {
				game.setSelectedIndex(game.getSelectedIndex() - 1);
				
				move = SahModel.getInstance().play(game.getSelectedIndex(), true);				
			}
			
			if(move.isCastle()) {
				Utils.playCastle();
			} else if(move.getDestroyedFigure() != R.drawable.selector && move.getDestroyedFigure() != R.drawable.empty) {
				Utils.playCapture();
			} else {
				Utils.playMove();
			}
			
			clearFilters();
			refreshDestroyedFigures();
			refreshMovesManager(game.getSelectedIndex());
			
			if(!game.isFinished() && SettingsModel.getInstance().isPlayOnClock() && !NewGame.ANALIZE.equals(game.getGameType())) {
				SahModel.getInstance().toggleClocks();
			}
			
			if(SahModel.getInstance().isAutoRotate() && !game.isTimeout() && NewGame.HUMAN.equals(game.getGameType())) rotate();
			
			showArrows();
			filterLastMove(move);
			
			SahModel.lastAction = ChessAction.PREVIOUS_MOVE;
		}
    }
    
    public void goToEnd() {
    	Game game = SahModel.getInstance().getGame();
    	
    	game.goToEnd();
		
		SahModel.lastAction = ChessAction.MOVE_TO_END;
		
		refreshTable(false);
		refreshDestroyedFigures();
		
		game.setSelectedIndex(game.getSelectedIndex() - 1);
		
		refreshMovesManager(game.getSelectedIndex());
		
		game.setSelectedIndex(game.getSelectedIndex() + 1);

		showArrows();
		
		clearFilters();
    }
    
    public void goToStart() {
    	Game game = SahModel.getInstance().getGame();
    	game.goToStart();
		
		SahModel.lastAction = ChessAction.MOVE_TO_START;

		showArrows();
		
		game.setSelectedIndex(game.getSelectedIndex() + 1);
		
		refreshTable(false);
		
		game.setSelectedIndex(game.getSelectedIndex() - 1);
		
		refreshDestroyedFigures();
		refreshMovesManager(game.getSelectedIndex());
		
		clearFilters();
    }
    
    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        Utils.setLanguage(SettingsModel.getInstance().getLanguage(), SahModel.context);
    	refresh(newConfig);
    	
        LinearLayout gridlayout = (LinearLayout) findViewById(R.id.gridlayout);
        
        Display display = this.getWindow().getWindowManager().getDefaultDisplay();
        
        int pivot = display.getWidth() > display.getHeight() ? display.getHeight() / 2 : display.getWidth() / 2;
        
        RotateAnimation anim = null;
        
        if(Utils.getOrientation() == 0 || Utils.getOrientation() == 2) anim = new RotateAnimation(90, 0, pivot, pivot);
        if(Utils.getOrientation() == 1 || Utils.getOrientation() == 3) anim = new RotateAnimation(-90, 0, pivot, pivot);
        
        anim.setDuration(500);
        anim.setInterpolator(new AccelerateDecelerateInterpolator());
        
        gridlayout.startAnimation(anim);
      
      super.onConfigurationChanged(newConfig);
    }
    
    public void refreshHeader() {
    	imageViewKnight = (ImageView)findViewById(R.id.imageViewKnight);
        emptyViewKnight = (ImageView)findViewById(R.id.emptyViewKnight);
        evalTextView = (TextView)findViewById(R.id.evalTextView);
    	
    	if(SahModel.getInstance().getWhiteClock().getParent() != null) {
        	((LinearLayout)SahModel.getInstance().getWhiteClock().getParent()).removeAllViews();
        }
        if(SahModel.getInstance().getBlackClock().getParent() != null) {
        	((LinearLayout)SahModel.getInstance().getBlackClock().getParent()).removeAllViews();
        }
        
        LinearLayout whiteClock = (LinearLayout)findViewById(R.id.whiteClock);
        LinearLayout blackClock = (LinearLayout)findViewById(R.id.blackClock);
        
        whiteClock.removeAllViews();
        if(SahModel.getInstance().getGame().isPlayOnClock()) {
        	whiteClock.addView(SahModel.getInstance().getWhiteClock());
        }
        
    	blackClock.removeAllViews();
        if(SahModel.getInstance().getGame().isPlayOnClock()) {
        	blackClock.addView(SahModel.getInstance().getBlackClock());
    	}
        
        TextView textViewWhite = (TextView)findViewById(R.id.textViewWhite);
        textViewWhite.setText(SahModel.getInstance().getGame().getPlayer1().getName() + (SahModel.getInstance().getGame().isPlayOnClock() ? ("\n" + SahModel.getInstance().getWhiteClock().getFormatedTime()) : ""));

        SahModel.getInstance().getWhiteClock().setTextView(textViewWhite);
        SahModel.getInstance().getWhiteClock().setPlayer(SahModel.getInstance().getGame().getPlayer1());
        
        TextView textViewBlack = (TextView)findViewById(R.id.textViewBlack);
        textViewBlack.setText(SahModel.getInstance().getGame().getPlayer2().getName() + (SahModel.getInstance().getGame().isPlayOnClock() ? ("\n" + SahModel.getInstance().getBlackClock().getFormatedTime()) : ""));

        SahModel.getInstance().getBlackClock().setTextView(textViewBlack);
        SahModel.getInstance().getBlackClock().setPlayer(SahModel.getInstance().getGame().getPlayer2());
    }
    
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	    if (requestCode == BluetoothPlugin.REQUEST_ENABLE_BT) {
	    	BluetoothPlugin.getInstance().onResult(resultCode, data);
	    }
	}
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	this.menu = menu;
    	
        MenuInflater inflater = getMenuInflater();
        
       // if(SettingsModel.getInstance().getLoggedUser() != null) {
        //	inflater.inflate(R.menu.chess_menu_signout, menu);
        //} else {
        	inflater.inflate(R.menu.chess_menu, menu);
        //}
        return true;
    }
    
    public void solveProblem(String fen, Integer mateIn) {
    	SahModel.getInstance().reset(fen);
    	
    	Game game = SahModel.getInstance().getGame();
    	
    	game.setGameType(NewGame.SOLVE_PROBLEM);
    	game.setPlayOnClock(false);
    	game.setMateIn(mateIn);
    	Game.COMPUTER_TIME = 5000;
    	
    	refreshDestroyedFigures();
		refreshMovesManager(game.getSelectedIndex());
		refreshTable(false);
		
		showArrows();
		
		game.getPlayer2().setName("Android");
		refreshHeader();
		
		/*if(SettingsModel.getInstance().getLoggedUser() != null) {
    		PublishActivityCall call = new PublishActivityCall(ActivityEnum.SOLVING_CHESS_PROBLEMS, SettingsModel.getInstance().getLoggedUser().getUsername(), SettingsModel.getInstance().getLoggedUser().getName(), "");			    		
    		SettingsModel.EXECUTOR_SERVICE.execute(call);
    		SettingsModel.getInstance().setLastActivity(ActivityEnum.SOLVING_CHESS_PROBLEMS);
    	}*/
    }
    
    public void playNewGame(NewGame newGame, boolean goToEnd) {
    	refresh(getResources().getConfiguration());
    	
    	Game game = SahModel.getInstance().getGame();
    	
    	game.setGameType(newGame);

    	if(!NewGame.BLUETOOTH.equals(newGame)) {
        	if(NewGame.ANALIZE.equals(newGame)) {
        		game.setPlayOnClock(false);
        		
        		/*if(SettingsModel.getInstance().getLoggedUser() != null) {
            		PublishActivityCall call = new PublishActivityCall(ActivityEnum.ANALYZING_GAMES, SettingsModel.getInstance().getLoggedUser().getUsername(), SettingsModel.getInstance().getLoggedUser().getName(), "");			    		
            		SettingsModel.EXECUTOR_SERVICE.execute(call);
            		SettingsModel.getInstance().setLastActivity(ActivityEnum.ANALYZING_GAMES);
            	}*/
        	} else {
        		game.setPlayOnClock(SettingsModel.getInstance().isPlayOnClock());
        	}
    	} /*else {
    		if(SettingsModel.getInstance().getLoggedUser() != null) {
        		PublishActivityCall call = new PublishActivityCall(ActivityEnum.PLAYING_THROUGH_BLUETOOTH_AGAINST, SettingsModel.getInstance().getLoggedUser().getUsername(), SettingsModel.getInstance().getLoggedUser().getName(), "");			    		
        		SettingsModel.EXECUTOR_SERVICE.execute(call);
        		SettingsModel.getInstance().setLastActivity(ActivityEnum.PLAYING_THROUGH_BLUETOOTH_AGAINST);
        	}
    	}*/
    	
		refreshDestroyedFigures();
		refreshMovesManager(game.getSelectedIndex());
		refreshTable(false);
		
		if(SahModel.getInstance().getGame().isPlayOnClock()) {
			if(SahModel.getInstance().getGame().getPlayer1().isWhitePlayer()) {
				SahModel.getInstance().getWhiteClock().start();
			} else {
				SahModel.getInstance().getBlackClock().start();
			}
		}
		
		game.checkDraw();

    	if(goToEnd)	{
    		goToEnd();
    		playNext();
    	}
		
		if(NewGame.COMPUTER.equals(newGame)) {
			game.getPlayer2().setName("Android");
    		refreshHeader();
    		
			if(!game.getCurrentPlayer().isWhitePlayer()) {
	    		game.playComputer();
		    }
    	}
    }
    
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	final ProgressBar progressBarAndroidThinking = (ProgressBar) findViewById(R.id.progressBarAndroidThinking);
    	
    	if(progressBarAndroidThinking != null && progressBarAndroidThinking.getVisibility() == ProgressBar.VISIBLE) {
    		Utils.displayToastMessage(this, getResources().getString(R.string.android_is_busy));
    		
    		return true;
    	}
    	
    	switch (item.getItemId()) {
	        case R.id.newgame:
	        	SahModel.getInstance().getGame().setGameType(null);
	        	
	        	if(!SahModel.getInstance().getGame().isWhitePlay() && SahModel.getInstance().isAutoRotate()) rotate();
	        	
	        	Utils.chooseNewGameType(this);
	        	
	        	refreshDestroyedFigures();
	    		refreshMovesManager(SahModel.getInstance().getGame().getSelectedIndex());
	    		refreshTable(false);
	    		showArrows();
	        	
	            return true;
	        case R.id.addgame:
	        	Intent intent2 = new Intent();
	        	intent2.setClass(this, AddPGNGameActivity.class);
	        	startActivity(intent2);
	        	
	            return true;
	        case R.id.settings:	        	
	        	Intent intent = new Intent();
	        	intent.setClass(this, SettingsActivity.class);
	        	startActivity(intent);
	        	
	        	return true;
	        case R.id.gamesexplorer:	        	
	        	Intent intent1 = new Intent();
	        	intent1.setClass(this, PGNGameActivity.class);
	        	startActivity(intent1);
	        	
	        	return true;
	        case R.id.about:
	        	Utils.displayAbout(this);
	        	
	        	try {
	        		   PackageInfo info = getPackageManager().getPackageInfo("com.black.knight.chess", PackageManager.GET_SIGNATURES);
	        		   for (Signature signature : info.signatures) {
	        		        MessageDigest md = MessageDigest.getInstance("SHA");
	        		        md.update(signature.toByteArray());
	        		        Log.d("Hash Key:", Base64.encodeToString(md.digest(), Base64.DEFAULT));
	        		   }
	        		} catch (NameNotFoundException e) {
	        			Log.d("NameNotFoundException", e.toString());
	        		} catch (NoSuchAlgorithmException e) {

	        		}
	        		        	
	        	return true;
	        case R.id.signin:
	        	Utils.displayToastMessage(this, "Black Kight Chess portal will be available in 2.0 version soon!");
	        	
	        	/*if(SettingsModel.getInstance().getLoggedUser() == null) {
	        		Intent intent3 = new Intent();
	        		intent3.setClass(this, SignInActivity.class);
	        		startActivity(intent3);
	        	} else {
	        		Intent intent4 = new Intent();
	        		intent4.setClass(this, ProfileActivity.class);
	        		startActivity(intent4);  		
	        	}*/
	        	return true;
	        default:
	            return super.onOptionsItemSelected(item);
        }
    }
    
    private OnClickListener previousClickListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			playPrevious();
		}
	};
	
	private OnClickListener nextClickListener = new OnClickListener() {
		@Override
		public void onClick(View v) {
			playNext();
		}
	};
	
	private boolean checkIfGameIsFinished(Integer index) {
		Game game = SahModel.getInstance().getGame();
		
		Move move = game.getMoves().get(index);
		
		Player whitePlayer = game.getPlayer1();
		Player blackPlayer = game.getPlayer2();
		if(!whitePlayer.isWhitePlayer()) {
			whitePlayer = game.getPlayer2();
			blackPlayer = game.getPlayer1();
		}
		
		Player notCurrentPlayer = game.getCurrentPlayer();
		if(notCurrentPlayer == game.getPlayer1()) notCurrentPlayer = game.getPlayer2(); else notCurrentPlayer = game.getPlayer1();

		if(move.isEndGame()) {
			if (move.getResult().equals("1-0")) {
				if(game.getMoves().get(index - 1).isCheckmate()) {
					Utils.displayGameFinishedMessage(SahModel.context, getResources().getString(R.string.checkmate) + " " + whitePlayer.getName() + " " + getResources().getString(R.string.win));
					
					try {
						PNGGamesModel.executor.execute(new Runnable() {
							@Override
							public void run() {
								try {
									Utils.playCheckMate();
									
									try {
										Thread.sleep(1500);
									} catch (InterruptedException e) { }
									
									Utils.playPlayer1Wins();
								} catch (Exception e) { }
							}
						});
					} catch (Exception e) { }
				} else {
					Utils.displayGameFinishedMessage(this, this.getResources().getString(R.string.game_is_finished) + " " + whitePlayer.getName() + " " + this.getResources().getString(R.string.win) + ", " + blackPlayer.getName() + " " + this.getResources().getString(R.string.resigned));
					
					Utils.playPlayer1Wins();
				}
			} else if(move.getResult().equals("0-1")) {
				if(game.getMoves().get(index - 1).isCheckmate()) {
					Utils.displayGameFinishedMessage(SahModel.context, getResources().getString(R.string.checkmate) + " " + blackPlayer.getName() + " " + getResources().getString(R.string.win));
					
					try {
						PNGGamesModel.executor.execute(new Runnable() {
							@Override
							public void run() {
								try {
									Utils.playCheckMate();
									
									try {
										Thread.sleep(1500);
									} catch (InterruptedException e) { }
									
									Utils.playPlayer2Wins();
								} catch (Exception e) { }
							}
						});
					} catch (Exception e) { }
				} else {
					Utils.displayGameFinishedMessage(this, this.getResources().getString(R.string.game_is_finished) + " " + blackPlayer.getName() + " " + this.getResources().getString(R.string.win) + ", " + whitePlayer.getName() + " " + this.getResources().getString(R.string.resigned));
					
					Utils.playPlayer2Wins();
				}
			} else if(move.isPat()) {
				Utils.displayGameFinishedMessage(this, this.getResources().getString(R.string.game_is_finished) + " " + this.getResources().getString(R.string.disadvantage));
			} else if(move.getResult().equals("1/2-1/2")) {
				Utils.displayGameFinishedMessage(this, this.getResources().getString(R.string.game_is_finished) + " " + this.getResources().getString(R.string.draw));
			} else if(move.getResult().equals("*")) {
				Utils.displayGameFinishedMessage(this, this.getResources().getString(R.string.game_is_finished));
			} else return false;
			
			game.setSelectedIndex(game.getSelectedIndex() + 1);
			
			clearFilters();
			refreshDestroyedFigures();
			showArrows();
			
			return true;
		} else if(move.isTimeout()) {
			Utils.displayGameFinishedMessage(this, this.getResources().getString(R.string.time_out) + notCurrentPlayer.getName() + this.getResources().getString(R.string.win));
			
			if(notCurrentPlayer == game.getPlayer1()) {
				Utils.playPlayer1Wins();
			} else {
				Utils.playPlayer2Wins();
			}
			return true;
		}
		
		return false;
	}
	
	public void refreshTable(boolean animate) {
		TableAdapter.animate = animate;
		
		GridView gridview = (GridView) findViewById(R.id.gridview);
		TableAdapter adapter = (TableAdapter)gridview.getAdapter();
		
		adapter.notifyDataSetChanged();
	}
	
	public void refreshDestroyedFigures() {
		GridView destroyedWhiteFigures = (GridView) findViewById(R.id.destroyedWhiteFigures);
		DestroyedFiguresAdapter adapter = (DestroyedFiguresAdapter)destroyedWhiteFigures.getAdapter();
		adapter.setWhite(SahModel.getInstance().getGame().getPlayer1().isWhitePlayer());
		
		adapter.notifyDataSetChanged();
		
		GridView destroyedBlackFigures = (GridView) findViewById(R.id.destroyedBlackFigures);
		DestroyedFiguresAdapter adapter1 = (DestroyedFiguresAdapter)destroyedBlackFigures.getAdapter();
		adapter1.setWhite(!SahModel.getInstance().getGame().getPlayer1().isWhitePlayer());
		
		adapter1.notifyDataSetChanged();
	}
	
	public void refreshMovesManager(int index) {				
		if(SettingsModel.getInstance().isShowEvaluation()) {
			SahModel.getInstance().getGame().refreshBoard();
			SahModel.getInstance().getGame().calculateEval();
		}
		
		LinearLayout movesview = (LinearLayout)findViewById(R.id.movesview);
		TextView moveTextView = (TextView)findViewById(R.id.moveTextView);
		
		if(SahModel.getInstance().getGame().getMoves().size() > 0) {
			if(index < SahModel.getInstance().getGame().getMoves().size()) {
				movesview.setVisibility(LinearLayout.VISIBLE);
				moveTextView.setVisibility(LinearLayout.VISIBLE);
				try {
					Move move = SahModel.getInstance().getGame().getMoves().get(index);
					ImageView movedFigure = (ImageView)findViewById(R.id.movedFigure);
					ImageView destroyedFigure = (ImageView)findViewById(R.id.destroyedFigure);
					TextView movedFigurePosition = (TextView)findViewById(R.id.movedFigurePosition);
					TextView destroyedFigurePosition = (TextView)findViewById(R.id.destroyedFigurePosition);
					
					movedFigure.setImageResource(move.getMovedFigure());
					movedFigurePosition.setText("- " + move.fromField());
					destroyedFigure.setImageResource(move.getDestroyedFigure());
					destroyedFigurePosition.setText("- " + move.toField());
					
					moveTextView.setText(getResources().getString(R.string.move) + ":" + (index + 1));
				} catch (ArrayIndexOutOfBoundsException e) {
				}
			}
		} else {
			movesview.setVisibility(LinearLayout.INVISIBLE);
			moveTextView.setVisibility(LinearLayout.INVISIBLE);
		}
		
	}
	
	public void clearFilters() {		
		for(int i = 0; i<64; i++) {
			if(SahModel.getInstance().getItem(i) == R.drawable.selector) {
				SahModel.getInstance().setFigure(i/8, i%8, R.drawable.empty);
			}
			
			SahModel.getInstance().getSelectedFlags()[i] = 0;
		}
		
		refreshTable(false);
	}
	
	private void filterFields(ArrayList<Move> list) {
		for (Move move : list) {
			
			if(!SettingsModel.getInstance().isMarkFields() && !(move.getRow() == move.getNewRow() && move.getColumn() == move.getNewColumn())) continue;
			
			if(SahModel.getInstance().getFigure(move.getNewRow(), move.getNewColumn()) == R.drawable.empty) {
				SahModel.getInstance().setFigure(move.getNewRow(), move.getNewColumn(), R.drawable.selector);
			}
			
			SahModel.getInstance().getSelectedFlags()[move.getNewPosition()] = 1;
		}
		
		refreshTable(false);
	}
	
	private void filterLastMove(Move move) {
		SahModel.getInstance().getSelectedFlags()[move.getPosition()] = 2;
		SahModel.getInstance().getSelectedFlags()[move.getNewPosition()] = 3;
		
		refreshTable(true);
	}
	
	public void markRecommendedMove(Move move) {
		SahModel.getInstance().getSelectedFlags()[move.getPosition()] = 4;
		SahModel.getInstance().getSelectedFlags()[move.getNewPosition()] = 5;
		
		refreshTable(false);
	}
    
    private OnItemClickListener itemClickListener = new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
        	final Game game = SahModel.getInstance().getGame();
        	
        	if(game == null || game.getGameType() == null) return;
        	
        	if(game.getGameType().equals(NewGame.SOLVE_PROBLEM)) {
    			Boolean solved = game.isSolved();
    			
    			if(solved != null) {
	    			if(solved == true) {
	    				Utils.displayAlertMessage(SahModel.context, getResources().getString(R.string.problem_solved));
	    			} else if(solved == false){
	    				Utils.displayAlertMessage(SahModel.context, getResources().getString(R.string.problem_failed));
	    			}
	    			return;
    			}
        	}
        	
        	if(game.isTimeout()) {
    			Utils.displayGameFinishedMessage(SahModel.context, getResources().getString(R.string.time_out) + " " + game.getWinner().getName() + " " + getResources().getString(R.string.win));
    			
    			if(game.getWinner().isWhitePlayer()) {
					Utils.playPlayer1Wins();	
				} else {
					Utils.playPlayer2Wins();
				}
    			return;
    		} else if(game.isSahMat()) {
    			String msg = "";
    			
    			if(game.getWinner() != null && game.getWinner().getName() != null) {
    				msg = " " + game.getWinner().getName() + " " + getResources().getString(R.string.win); 
    			}
    			
    			Utils.displayGameFinishedMessage(SahModel.context, getResources().getString(R.string.checkmate) + msg);
    			
				try {
	    			PNGGamesModel.executor.execute(new Runnable() {
						@Override
						public void run() {
							try {
								Utils.playCheckMate();
								
								if(game.getWinner() == null) return;
								
								try {
									Thread.sleep(1500);
								} catch (InterruptedException e) { }
								
								if(game.getWinner().isWhitePlayer()) {
									Utils.playPlayer1Wins();	
								} else {
									Utils.playPlayer2Wins();
								}
							} catch (Exception e) { }
						}
					});
				} catch (Exception e) { }
    			return;
    		} else if(game.isPat()) {
    			Utils.displayGameFinishedMessage(SahModel.context, getResources().getString(R.string.disadvantage));
    			return;
    		} else if(game.isDraw()) {
				Utils.displayGameFinishedMessage(SahModel.context, getResources().getString(R.string.draw));
				return;
			}
    		
        	if(!NewGame.HUMAN.equals(game.getGameType()) && game.getWinner() != null) return;
        	
        	if(game.getGameType().equals(NewGame.BLUETOOTH) && game.getCurrentPlayer() != game.getPlayer1()) {
        		return;
        	}
        	
        	if(!game.getGameType().equals(NewGame.HUMAN) && !game.getGameType().equals(NewGame.ANALIZE) && !game.getPlayer1().isWhitePlayer()) {
        		position = 63 - position;
        	}
        	
        	if(SahModel.getInstance().isAutoRotate() && !game.getPlayer1().isWhitePlayer() && game.getGameType().equals(NewGame.HUMAN)) position = 63 - position;
        	
        	GridView gridview = (GridView) findViewById(R.id.gridview);
        	
        	TableAdapter adapter = (TableAdapter)gridview.getAdapter();
        	
        	clearFilters();
        	
        	if(move != null) {
        		if(game.isWhitePlay() != Move.isFigureWhite(move.getFigure())) {
        			move = new Move(position);
        			
        			if(!Move.isFigure(move.getFigure())) {
        				move = null;
        				return;
        			}
        			
        			if(Move.isFigureWhite(move.getFigure()) == game.isWhitePlay()) {
        				ArrayList<Move> moves = move.getPosibleMoves();
        				filterFields(moves);
        			}
            		
        			return;
        		}
        		    			
        		move.setNewPosition(position);
        		
            	if(move.check()) {
    				if(move.isPromote()) {
    					ChessUtil.chooseFigure(SahModel.context, move);
    					return;
    				}
    				
    				if(ChessUtil.playMove(SahModel.context, move)) return;
            	}
        	} else if(adapter.getItem(position) == R.drawable.empty || adapter.getItem(position) == R.drawable.selector) {
        		gridview.setSelection(-1);
        		return;
        	} 
    			
        	move = new Move(position);
        	
        	if(Move.isFigureWhite(move.getFigure()) == game.isWhitePlay() && Move.isFigure(move.getFigure())) {
        		ArrayList<Move> moves = move.getPosibleMoves();
        		filterFields(moves);
        	}
        }
    };
    
    public boolean playMove(Move move) {
		boolean toggleClocks = true;
		
		final Game game = SahModel.getInstance().getGame();
		
		move.execute(game.getSelectedIndex(), true);
		
		if(move.isSah()) {
			SahModel.getInstance().play(game.getSelectedIndex(), true);
			game.getMoves().remove(game.getMoves().size() - 1);
			
			Utils.displayAlertMessage(this, getResources().getString(R.string.check) + " " + getResources().getString(R.string.invalid_move));
			Utils.playCheck();
			
			game.togglePlayer();
			
			return false;
		} else {
			game.togglePlayer();
			
			if(move.isSah()) {
				if(move.isSahMat()) {
					game.finish(true);
					move.setEndGame(true);
					move.setCheckmate(true);
					
					Utils.displayGameFinishedMessage(this, getResources().getString(R.string.checkmate) + " " + game.getWinner().getName() + " " + getResources().getString(R.string.win));
					
					try {
						PNGGamesModel.executor.execute(new Runnable() {
							@Override
							public void run() {
								try {
									Utils.playCheckMate();
									
									try {
										Thread.sleep(1500);
									} catch (InterruptedException e) { }
									
									
									if(game.getWinner() == null) return;
									
									if(game.getWinner().isWhitePlayer()) {
										Utils.playPlayer1Wins();	
									} else {
										Utils.playPlayer2Wins();
									}
								} catch (Exception e) { }
							}
						});
					} catch (Exception e) { }
					
					toggleClocks = false;
				} else {
					Utils.displayToastMessage(this, getResources().getString(R.string.check));
					Utils.playCheck();
					move.setCheck(true);
				}
			} else if(move.isSahMat()) {
				Utils.displayGameFinishedMessage(this, getResources().getString(R.string.disadvantage));
				
				game.finish(false);
				
				move.setCheckmate(false);
				move.setPat(true);
				move.setEndGame(true);
				toggleClocks = false;
			} else if(game.checkDraw()) {				
				game.finish(false);
				
				move.setCheckmate(false);
				move.setDraw(true);
				move.setEndGame(true);
				toggleClocks = false;
			}
			
			move.postProcessPGN();
		}
		
		if(move.isCastle()) {
			Utils.playCastle();
		} else if(move.getDestroyedFigure() != R.drawable.selector && move.getDestroyedFigure() != R.drawable.empty) {
			Utils.playCapture();
		} else {
			Utils.playMove();
		}
				
		refreshTable(false);
		refreshMovesManager(game.getSelectedIndex());
		
		if(move.getDestroyedFigure() != R.drawable.selector) {
			refreshDestroyedFigures();
		}
		
		game.setSelectedIndex(game.getMoves().size());
		showArrows();
		
		if(game.getGameType().equals(NewGame.SOLVE_PROBLEM)) {
			Boolean solved = game.isSolved();
			
			if(solved != null) {
				if(solved == true) {
					Utils.displayAlertMessage(this, getResources().getString(R.string.problem_solved));
				} else if(solved == false){
					Utils.displayAlertMessage(this, getResources().getString(R.string.problem_failed));
				}
			}
		}
		
		if(move.isEndGame()) {
			Move newMove = new Move(0);
			newMove.setEndGame(true);
			if(move.isPat() || move.isDraw()) {
				newMove.setResult("1/2-1/2");
			} else if(move.isCheckmate()) {
				newMove.setCheckmate(true);
				if(Move.isFigureWhite(move.getNewFigure())) newMove.setResult("1-0");
				if(Move.isFigureBlack(move.getNewFigure())) newMove.setResult("0-1");
			}
			
			newMove.postProcessPGN();
			
			game.getMoves().add(newMove);
			
			game.setSelectedIndex(game.getMoves().size());
		}
		
		if(toggleClocks && SahModel.getInstance().getGame().isPlayOnClock() && !NewGame.ANALIZE.equals(game.getGameType())) {
			SahModel.getInstance().toggleClocks();
		}
        
		if(SahModel.getInstance().isAutoRotate()) rotate();
		
		filterLastMove(move);
		
		SahModel.lastAction = ChessAction.MOVE;
		
		if(SettingsModel.getInstance().isRecognizeGame()) ChessUtil.displayCurrentOpening();
		
		if(SettingsModel.getInstance().isShowEvaluation() || SettingsModel.getInstance().isRecommendMove() || NewGame.COMPUTER.equals(game.getGameType()) || NewGame.SOLVE_PROBLEM.equals(game.getGameType())) {
			game.refreshBoard();
		}
		
		if((NewGame.COMPUTER.equals(game.getGameType()) || NewGame.SOLVE_PROBLEM.equals(game.getGameType())) && game.getCurrentPlayer() == game.getPlayer2() && !game.isFinished()) {
			game.playComputer();
		} else {
			if(SettingsModel.getInstance().isRecommendMove()) {
				game.recommendMove();	
			}
		}
		
		return true;
    }
    
    public void rotate() {    	
    	Game game = SahModel.getInstance().getGame();
    	
    	if(Utils.geOldtOrientation() == Surface.ROTATION_90) {
    		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE);
    	} else if(Utils.geOldtOrientation() == Surface.ROTATION_0) {
    		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT);
    	} else if(Utils.geOldtOrientation() == Surface.ROTATION_270) {
    		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
    	} else if(Utils.geOldtOrientation() == Surface.ROTATION_180) {
    		setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
    	}
    	
    	game.switchPlayers();
    	
    	refreshDestroyedFigures();
    	refreshTable(false);
    	setVisible(true);
    	
    	GridView gridview = (GridView) findViewById(R.id.gridview);
    	if(game.getPlayer1().isWhitePlayer()) {
        	gridview.setBackgroundResource(R.drawable.background);
        } else {
        	gridview.setBackgroundResource(R.drawable.background1);
        }
    }
    
    private void showArrows() {
		ImageButton buttonPrevious = (ImageButton) findViewById(R.id.buttonPrevious);
		ImageButton buttonNext = (ImageButton) findViewById(R.id.buttonNext);
		
		Game game = SahModel.getInstance().getGame();
		
		if(!game.isFinished() && NewGame.BLUETOOTH.equals(game.getGameType()) || game.getMoves().size() == 0) {
			buttonNext.setVisibility(ImageButton.INVISIBLE);
			buttonPrevious.setVisibility(ImageButton.INVISIBLE);
		} else {
			if(game.getSelectedIndex() > 0) {
				buttonPrevious.setVisibility(ImageButton.VISIBLE);	
			} else {
				buttonPrevious.setVisibility(ImageButton.INVISIBLE);
			}
			
			if(game.getSelectedIndex() < game.getMoves().size()) {
				buttonNext.setVisibility(ImageButton.VISIBLE);
			} else {
				buttonNext.setVisibility(ImageButton.INVISIBLE);
			}
		}
		
		refreshKnight(game.getCurrentPlayer());
    }
    
	private void refreshKnight(Player currentPlayer) {
		ImageView animKnight = imageViewKnight;
		emptyViewKnight.setImageResource(R.drawable.empty);
		
		int value = 100;
		
    	if(!SahModel.getInstance().getGame().getPlayer1().isWhitePlayer()) {
    		value *= -1;
    		
    		if(currentPlayer.isWhitePlayer()) {
    			animKnight = emptyViewKnight;
    			imageViewKnight.setImageResource(R.drawable.empty);
    		}
    	} else {
    		if(!currentPlayer.isWhitePlayer()) {
    			animKnight = emptyViewKnight;
    			imageViewKnight.setImageResource(R.drawable.empty);
    		}
    	}
		
		TranslateAnimation anim = null;
		if(animKnight != null) {
	    	if(currentPlayer.isWhitePlayer()) {
	    		animKnight.setImageResource(R.drawable.wn);
				if(Utils.getOrientation() == Surface.ROTATION_0 || Utils.getOrientation() == Surface.ROTATION_180) {
					anim = new TranslateAnimation(value, 0, 0, 0);
				} else {
					anim = new TranslateAnimation(0, 0, value, 0);
				}
			} else {
				animKnight.setImageResource(R.drawable.bn);
				if(Utils.getOrientation() == Surface.ROTATION_0 || Utils.getOrientation() == Surface.ROTATION_180) {
					anim = new TranslateAnimation(-value, 0, 0, 0);
				} else {
					anim = new TranslateAnimation(0, 0, -value, 0);
				}
			}
	    	
	    	anim.setDuration(300);
	        anim.setInterpolator(new AccelerateDecelerateInterpolator());
	    	
	        animKnight.startAnimation(anim);
	    }
	}
    
    public void setMove(Move move) {
		this.move = move;
	}
    
    public TextView getEvalTextView() {
		return evalTextView;
	}
}